# python3.6
import os
from ftplib import FTP
from io import BytesIO
import zipfile
import configparser
import time
import socket
import datetime
import fnmatch

class DownFtp:

    def __init__(self, host, logName, port=21):
        """ 初始化 FTP 客户端
        参数:
                 host:ip地址

                 port:端口号
        """

        self.host = host
        self.port = port
        self.ftp = FTP()
        # 重新设置下编码方式
        # self.ftp.encoding = 'utf-8'
        self.log_file = open("./ftpLog/" + logName + time.strftime("%Y%m%d", time.localtime(time.time())) + ".txt", "a",
                             encoding="utf-8")

    def login(self, username, password):
        """ 初始化 FTP 客户端
            参数:
                  username: 用户名

                 password: 密码
            """
        try:
            timeout = 120
            socket.setdefaulttimeout(timeout)
            # 0主动模式 1 #被动模式
            # self.ftp.set_pasv(False)
            # 打开调试级别2，显示详细信息
            # self.ftp.set_debuglevel(1)

            self.write_log('开始尝试连接到 %s' % self.host)
            self.ftp.connect(self.host, self.port)
            self.write_log('成功连接到 %s' % self.host)

            self.write_log('开始尝试登录到 %s' % self.host)
            self.ftp.login(username, password)
            self.write_log('成功登录到 %s' % self.host)

            self.write_log(self.ftp.welcome)
            return True
        except Exception as err:
            self.write_log("FTP 连接或登录失败 ，错误描述为：%s" % err)
            return False
            pass

    def DownLoadFile(self, localFile):  # 下载当个文件

        bio = BytesIO()
        self.ftp.retrbinary('RETR ' + localFile, callback=bio.write)
        bio.seek(0)

        # 创建压缩文件对象
        self.zip_out.writestr(localFile, bio.getvalue())
        self.write_log("添加" + localFile + "进zip文件")
        return True


    # 使用通配符来匹配过滤文件名
    def list_files_with_pattern(self, pattern):
        files = []
        #listings = self.ftp.mlsd()  # 获取目录列表和文件信息
        listings = self.ftp.nlst() # 获取目录列表
        #for name in (info[0] for info in listings):  # info[0] 是文件名
        if pattern in ("*", ""):
            return listings
        else:
            for name in listings:  # info[0] 是文件名
                #print(name)
                #self.write_log("get filename:" + name)
                if fnmatch.fnmatch(name, pattern):  # 使用fnmatch进行模式匹配
                    files.append(name)
            return files

    def DownLoadFileTree(self, LocalDir, RemoteDir, currenTime, lastTime, todayStr, key, pattern):  # 下载整个目录下的文件
        self.write_log("remoteDir:" + RemoteDir)

        try:
            self.ftp.cwd(RemoteDir)
        except Exception as err:
            self.write_log('远程目录%s不存在，继续...' % RemoteDir + " ,具体错误描述为：%s" % err)
            return False

        # 20250223 使用模式匹配文件
        # RemoteNames = self.ftp.nlst()
        RemoteNames = self.list_files_with_pattern(pattern)

        for file in RemoteNames:
            Local = os.path.join(LocalDir, file)

            if key.split("_")[0] == "sc" and key.split("_")[2] == "18" and key.split("_")[1] == "5":
                rm = "MDTM " + RemoteDir + file
                fileDate = self.ftp.voidcmd(rm)[4:].strip()

                lastDate = datetime.datetime.strptime(todayStr + lastTime + "00",
                                                      "%Y%m%d%H%M%S") + datetime.timedelta(days=-1)
                currenDate = datetime.datetime.strptime(todayStr + currenTime + "00", "%Y%m%d%H%M%S")
                fileDate = datetime.datetime.strptime(fileDate, "%Y%m%d%H%M%S")
                if lastDate <= fileDate < currenDate:
                    self.DownLoadFile(file)
            elif file.find(".") == -1:
                fileDate = "20200625004712"
                typelits = key.split("_")

                isSix = False
                if typelits[1] == "6" or typelits[1] == "9":
                    if typelits[0] == "sc" or typelits[0] == "lc" :
                        isSix = True

                if len(fileDate) < 14:
                    fileDate = fileDate + "00"

                lastDate = datetime.datetime.strptime(todayStr + lastTime + "00",
                                                      "%Y%m%d%H%M%S") + datetime.timedelta(days=-1)
                currenDate = datetime.datetime.strptime(todayStr + currenTime + "00", "%Y%m%d%H%M%S")
                fileDate = datetime.datetime.strptime(fileDate, "%Y%m%d%H%M%S")
                if lastDate <= fileDate < currenDate or isSix:
                    self.DownLoadFile(file)
            else:
                fileNameList = file.split(".")
                fileDate = "20200625004712"
                typelits = key.split("_")
                if typelits[0] == "acc":
                    # acc下发的对账文件，文件名有点，但是要整目录抓取
                    self.DownLoadFile(file)
                else:
                    if typelits[1] == "2" or typelits[1] == "14" or typelits[1] == "36":
                        fileDate = fileNameList[3]

                    if typelits[1] == "1" or typelits[1] == "5" or typelits[1] == "10" or typelits[1] == "16":
                        if typelits[0] == "lc":
                            fileDate = fileNameList[1]
                        if typelits[0] == "sc":
                            fileDate = fileNameList[2]

                    if typelits[1] == "3":
                        if typelits[0] == "lc":
                            fileDate = fileNameList[5]
                        if typelits[0] == "sc":
                            fileDate = fileNameList[3]

                    if typelits[1] == "4":
                        if typelits[0] == "lc":
                            fileDate = fileNameList[1]
                        if typelits[0] == "sc":
                            fileDate = fileNameList[2]

                    # 20250223 增加9号线TVM故障退款情况 ，类似：FFFF_custom_packed_20250128.tar.gz 或者 0925_custom_packed_20250122.tar
                    if typelits[1] == "9":
                        #fileDate = fileNameList[0][-8:] + lastTime + "00"
                        fileDate = fileNameList[0][-8:]

                    if len(fileDate) == 8:
                        fileDate = fileDate + lastTime

                    if len(fileDate) < 14:
                        # fileDate = fileDate + "00"
                        # 20250225 改成填充14位方式
                        fileDate = fileDate.ljust(14,'0')

                    lastDate = datetime.datetime.strptime(todayStr + lastTime + "00",
                                                          "%Y%m%d%H%M%S") + datetime.timedelta(days=-1)
                    currenDate = datetime.datetime.strptime(todayStr + currenTime + "00", "%Y%m%d%H%M%S")
                    fileDate = datetime.datetime.strptime(fileDate, "%Y%m%d%H%M%S")

                    if lastDate <= fileDate < currenDate:
                        self.DownLoadFile(file)

        self.ftp.cwd("..")
        return True

    def close(self):
        self.write_log(self.zip_name + "zip打包完毕")
        self.zip_out.close()
        self.ftp.quit()

    def write_log(self, log_str):
        """ 记录日志
            参数：
                log_str：日志
        """
        time_now = time.localtime()
        date_now = time.strftime('%Y-%m-%d-%H%M%S', time_now)
        format_log_str = "%s ---> %s \n " % (date_now, log_str)
        self.log_file.write(format_log_str)
        # print(format_log_str)

    def creatZip(self, name):
        self.zip_out = zipfile.ZipFile("./saveZip/" + name, 'w', zipfile.ZIP_DEFLATED)
        self.zip_name = name


if __name__ == "__main__":
    ftp = DownFtp("127.0.0.1", "anonymous")

    todayStr = time.strftime("%Y-%m-%d", time.localtime(time.time()))
    ftp.zip_out = zipfile.ZipFile("./saveZip/" + todayStr, 'w', zipfile.ZIP_DEFLATED)

    ftp.login("anonymous", "1")
    ftp.DownLoadFileTree("./saveZip/", "/1/", "0200", "0200", "20210625", "sc_5_18_1.zip", "")  # 从目标目录下载到本地目录d盘
    ftp.close()
    ftp.zip_out.close()
